home *** CD-ROM | disk | FTP | other *** search
/ Complete Linux / Complete Linux.iso / docs / system / mail / transpor / ifmail23.z / ifmail23 / ifmail / ifcico / openfile.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-04-09  |  4.7 KB  |  234 lines

  1. #include <unistd.h>
  2. #include <stdlib.h>
  3. #include <stdio.h>
  4. #include <string.h>
  5. #include <sys/types.h>
  6. #include <sys/stat.h>
  7. #include <time.h>
  8. #include <utime.h>
  9. #include <fcntl.h>
  10. #include "xutil.h"
  11. #include "lutil.h"
  12. #include "config.h"
  13.  
  14. extern unsigned long sequencer(void);
  15.  
  16. static FILE *infp=NULL;
  17. static char *infpath=NULL;
  18. static time_t intime;
  19. static int isfreq;
  20. char *freqname=NULL;
  21.  
  22. /*
  23.    Try to find present (probably incomplete) file with the same timestamp
  24.    (it might be renamed), open it for append and store resync offset.
  25.    Store 0 in resync offset if the file is new. Return FILE* or NULL.
  26.    resync() must accept offset in bytes and return 0 on success, nonzero
  27.    otherwise (and then the file will be open for write).  For Zmodem,
  28.    resync is always possible, but for SEAlink it is not.  Do not try
  29.    any resyncs if remsize == 0.
  30. */
  31.  
  32. FILE *openfile(char*,time_t,off_t,off_t*,int(*)(off_t));
  33. FILE *openfile(fname,remtime,remsize,resofs,resync)
  34. char *fname;
  35. time_t remtime;
  36. off_t remsize;
  37. off_t *resofs;
  38. int (*resync)(off_t);
  39. {
  40.     char *opentype;
  41.     char *p,x;
  42.     char ctt[32];
  43.     int rc,ncount;
  44.     struct stat st;
  45.     struct flock fl = {
  46.         F_WRLCK,
  47.         0,
  48.         0L,
  49.         0L,
  50.         0
  51.     };
  52.     char tmpfname[16];
  53.  
  54.     strcpy(ctt,date(remtime));
  55.     debug(11,"openfile(\"%s\",%s,%lu,...)",fname,ctt,remsize);
  56.  
  57.     if ((fname == NULL) || (fname[0] == '\0'))
  58.     {
  59.         sprintf(tmpfname,"%08lx.pkt",sequencer());
  60.         fname=tmpfname;
  61.     }
  62.     if (infpath) free(infpath);
  63.     infpath=xstrcpy(inbound);
  64.     infpath=xstrcat(infpath,"/tmp/");
  65.     infpath=xstrcat(infpath,fname);
  66.  
  67.     if ((strlen(fname) == 12) &&
  68.         (strspn(fname,"0123456789abcdefABCDEF") == 8) &&
  69.         (strcasecmp(fname+8,".req") == 0))
  70.     {
  71.         debug(12,"received wazoo freq file");
  72.         isfreq=1;
  73.     }
  74.     else isfreq=0;
  75.  
  76. /*
  77.     Renaming algorythm is as follows: start with the present name,
  78.     increase the last character of the file name, jumping from 
  79.     '9' to 'a', from 'z' to 'A', from 'Z' to '0'. If _all_ these 
  80.     names are occupied, 
  81. */
  82.  
  83.     p=infpath+strlen(infpath)-1;
  84.     x=*p;
  85.     ncount=0;
  86.     while (((rc=stat(infpath,&st)) == 0) &&
  87.            (remtime != st.st_mtime) &&
  88.            (ncount++ < 62))
  89.     {
  90.         if (x == '9') x='a';
  91.         else if (x == 'z') x='A';
  92.         else if (x == 'Z') x='0';
  93.         else x++;
  94.         *p=x;
  95.     }
  96.     if (isfreq || (ncount >= 62)) /* names exhausted */
  97.     {
  98.         rc=1;
  99.         p=strrchr(infpath,'/');
  100.         *p='\0';
  101.         p=tempnam(infpath,",");
  102.         free(infpath);
  103.         infpath=xstrcpy(p); /* tempnam() returns pointer to a static
  104.                     buffer, right? */
  105.     }
  106.     *resofs=0L;
  107.     opentype="w";
  108.     if ((rc == 0) && (remsize != 0))
  109.     {
  110.         loginf("resyncing at offset %lu of \"%s\"",st.st_size,infpath);
  111.         if (resync(st.st_size) == 0)
  112.         {
  113.             opentype="a";
  114.             *resofs=st.st_size;
  115.         }
  116.     }
  117.     debug(11,"try fopen(\"%s\",\"%s\")",infpath,opentype);
  118.     if ((infp=fopen(infpath,opentype)) == NULL)
  119.     {
  120.         logerr("$cannot open local file \"%s\" for \"%s\"",
  121.             infpath,opentype);
  122.         free(infpath);
  123.         infpath=NULL;
  124.         return NULL;
  125.     }
  126.     fl.l_pid=getpid();
  127.     if (fcntl(fileno(infp),F_SETLK,&fl) != 0)
  128.     {
  129.         loginf("$cannot lock local file \"%s\"",infpath);
  130.         fclose(infp);
  131.         infp=NULL;
  132.         free(infpath);
  133.         infpath=NULL;
  134.         return NULL;
  135.     }
  136.     intime=remtime;
  137.  
  138.     if (isfreq)
  139.     {
  140.         if (freqname) free(freqname);
  141.         freqname=xstrcpy(infpath);
  142.     }
  143.  
  144.     debug(11,"opened file \"%s\" for \"%s\", restart at %lu",
  145.         infpath,opentype,*resofs);
  146.     return infp;
  147. }
  148.  
  149. /*
  150.    close file and if (success) { move it to the final location }
  151. */
  152.  
  153. int closefile(int);
  154. int closefile(success)
  155. int success;
  156. {
  157.     char *newpath,*p;
  158.     int rc=0,ncount;
  159.     char x;
  160.     struct stat st;
  161.     struct utimbuf ut;
  162.  
  163.     debug(11,"closefile(%d), for file \"%s\"",success,infpath);
  164.  
  165.     if ((infp == NULL) || (infpath == NULL))
  166.     {
  167.         logerr("internal error: try close unopened file!");
  168.         return 1;
  169.     }
  170.  
  171.     rc=fclose(infp);
  172.     infp=NULL;
  173.  
  174.     if (rc == 0)
  175.     {
  176.         ut.actime=intime;
  177.         ut.modtime=intime;
  178.         if ((rc=utime(infpath,&ut)))
  179.         {
  180.             logerr("$utime failed");
  181.         }
  182.     }
  183.  
  184.     if (isfreq)
  185.     {
  186.         if ((rc != 0) || (!success))
  187.         {
  188.             loginf("removing unsuccessfully received wazoo freq");
  189.             unlink(freqname);
  190.             free(freqname);
  191.             freqname=NULL;
  192.         }
  193.         isfreq=0;
  194.     }
  195.     else if ((rc == 0) && success)
  196.     {
  197.         newpath=xstrcpy(inbound);
  198.         newpath=xstrcat(newpath,strrchr(infpath,'/'));
  199.         
  200.         p=newpath+strlen(newpath)-1;
  201.         x=*p;
  202.         ncount=0;
  203.         while (((rc=stat(newpath,&st)) == 0) &&
  204.                (ncount++ < 62))
  205.         {
  206.             if (x == '9') x='a';
  207.             else if (x == 'z') x='A';
  208.             else if (x == 'Z') x='0';
  209.             else x++;
  210.             *p=x;
  211.         }
  212.         if (ncount >= 62) /* names exhausted */
  213.         {
  214.             rc=1;
  215.             p=strrchr(newpath,'/');
  216.             *p='\0';
  217.             p=tempnam(newpath,",");
  218.             free(newpath);
  219.             newpath=xstrcpy(p); /* tempnam() returns pointer to 
  220.                         a static buffer, right? */
  221.         }
  222.  
  223.         debug(11,"moving \"%s\" -> \"%s\"",infpath,newpath);
  224.         rc=rename(infpath,newpath);
  225.         if (rc) logerr("$error renaming \"%s\" -> \"%s\"",
  226.                 infpath,newpath);
  227.  
  228.         free(newpath);
  229.     }
  230.     free(infpath);
  231.     infpath=NULL;
  232.     return rc;
  233. }
  234.